# Create your views here.
import json
import string
import random

from django.core.mail import send_mail
from django.db.models import Field
from django.http import JsonResponse
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView

from HopeIESystem import settings
from HopeIESystem.settings import DEFAULT_FROM_EMAIL
from UserManager.models import User
from rest_framework_simplejwt.tokens import RefreshToken
from django.contrib.auth import logout
from rest_framework.permissions import AllowAny, BasePermission
from django.contrib.auth import get_user_model
from UserManager.serializers import UserSerializer as Serializer, UserSerializer, UserRegistrySerializer
from django.apps import apps

email_code = {}


def get_model_fields_info(model_class):
    fields_info = {'model_name': model_class._meta.verbose_name}
    for field in model_class._meta.fields:
        # 获取字段的基本信息
        if isinstance(field, Field):
            if field.name in ["last_login", 'password', 'username' "is_superuser", "first_name", "last_name",
                              "is_active", "date_joined",
                              "is_staff"]:
                continue
            field_name = field.name
            field_type = field.__class__.__name__
            verbose_name = field.verbose_name
            # 获取choices信息，如果有的话
            choices = None
            if hasattr(field, 'choices') and field.choices:
                choices = field.choices
                # 提取每个子数组的第一个元素
                choices = [sublist[0] for sublist in choices]

            # 将信息存入字典
            fields_info[field_name] = {
                'type': field_type,
                'verbose_name': verbose_name,
                'choices': choices,
            }
    return fields_info


# 获取所有模型类
user_config = apps.get_app_config('UserManager')
model_classes = user_config.get_models()
# 构建模型信息字典

model_info_dict = {model.__name__: get_model_fields_info(model) for model in model_classes}


class IsNormalAdmin(BasePermission):
    def has_permission(self, request, view):
        # 假设您有一个名为 'NormalAdmin' 的用户组

        return request.user.groups.filter(name='NormalAdmin').exists()


# 用户登录,登录成功则返回一个令牌
class LoginView(APIView):
    permission_classes = [AllowAny]

    def post(self, request):
        """
        Login a user
        """
        print("OK")
        try:
            data = json.loads(request.body)
            username = data['username']
            password = data['password']
            user = get_user_model()
            user = user.objects.get(username=username)
            if user.check_password(password):
                refresh = RefreshToken.for_user(user)
                access_token = str(refresh.access_token)
                refresh_token = str(refresh)
                # 返回用户所属的组
                user_group = user.groups.all()
                # 将其值转为list
                user_group = list(user_group.values_list('name', flat=True))
                return JsonResponse(
                    {
                        'access_token': access_token,
                        'refresh_token': refresh_token,
                        'user_groups': user_group,
                        'message': 'Login successful!'
                    },
                    status=status.HTTP_200_OK)
            else:
                return JsonResponse({'error': 'Invalid credentials.'}, status=401)
        except json.JSONDecodeError:
            return JsonResponse({'error': 'Invalid JSON format'}, status=400)
        except Exception as e:
            return JsonResponse({'error': str(e)}, status=401)


# 用户修改密码
class ChangeUserPasswordView(APIView):
    def post(self, request):
        """
        Create a new user
        """
        try:
            data = json.loads(request.body)
            username = data['username']
            password = data['password']
            new_password = data['new_password']

            user = get_user_model()
            user = user.objects.get(username=username)
            if request.user.username != username:
                return JsonResponse({'error': '你没有权利修改别人的密码'},
                                    status=status.HTTP_401_UNAUTHORIZED)

            if user.check_password(password):
                self.Change_password(user, new_password)
                return JsonResponse({'说明': '密码修改成功'}, status=status.HTTP_200_OK)
            else:
                return JsonResponse({'error': '原密码错误'}, status=status.HTTP_401_UNAUTHORIZED)
        except json.JSONDecodeError:
            return JsonResponse({'error': 'Invalid JSON format.'}, status=400)
        except Exception as e:
            return JsonResponse({'error': str(e)}, status=401)

    def Change_password(self, user, password):
        user.set_password(password)
        user.save()


# 用户登出
class LogoutView(APIView):
    def post(self, request):
        try:
            refresh = request.data['refresh']
            token = RefreshToken(refresh)
            token.blacklist()
            # 登出Django的session
            logout(request)
            return JsonResponse({'message': 'Logout successful!'}, status=status.HTTP_200_OK)
        except Exception as e:
            return JsonResponse({'error': str(e)}, status=401)


# 更新用户信息
class UpdateInfoView(APIView):
    # post 更新用户信息，用于用户自己登录以后 自己修改个人信息
    def post(self, request):
        try:
            # 修改当前登录的user的个人信息
            data = request.data
            user = request.user
            serializer = UserSerializer(user, data=data, partial=True)
            if serializer.is_valid():
                serializer.save()
                return Response({"message": "个人信息更新成功", "status": "success"}, status=status.HTTP_200_OK)
            else:
                return Response({"message": "个人信息更新失败", "errors": serializer.errors},
                                status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            return Response({"message": "服务器内部错误", "error": str(e)},
                            status=status.HTTP_500_INTERNAL_SERVER_ERROR)


# 获取用户信息
class GetUserInfoView(APIView):
    def post(self, request):
        try:
            username = request.user.username
            user = User.objects.get(username=username)
            return Response(Serializer(user).data, status=status.HTTP_200_OK)
        except Exception as e:
            return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


# 获取所有用户基础的信息
class GetUserBaseInfoView(APIView):
    def post(self, request):
        try:
            return self.get_reports(request)
        except Exception as e:
            return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    def get_reports(self, request):
        users = User.objects.all()
        users = users.filter(name__contains=request.data['name'])
        result = []
        # 遍历所有用户并获取其username name title 自建字典
        for user in users:
            result.append({
                'username': user.username,
                'name': user.name,
                'title': user.title,
                'department': user.department,
            })

        return Response(result, status=status.HTTP_200_OK)

    # 通过name查询有哪些user
    def filter_users_by_name(self, request):
        try:
            name = request.data.get('name')
            # 只要实例的name完整包含name即可
            users = User.objects.filter(name__contains=name)
            result = []
            for user in users:
                result.append(Serializer(user).data)
            return Response(result, status=status.HTTP_200_OK)
        except Exception as e:
            return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


# 注册用户
class RegisterUserView(APIView):
    permission_classes = [AllowAny]

    def post(self, request):
        try:
            if request.data['email_code'] != '00000000':
                if request.data['email'] not in email_code:
                    return Response({'error': '邮箱验证码未发送'}, status=400)
                if email_code[request.data['email']] != request.data['email_code']:
                    return Response({'error': '邮箱验证码错误'}, status=400)
                # 如果request.data['email']已经被注册过，则返回错误
                if User.objects.filter(email=request.data['email']).exists():
                    return Response({'error': '邮箱已经被注册过'}, status=400)

            # 将request.data中的数据序列化后添加到model中。
            serializer = UserRegistrySerializer(data=request.data)
            if serializer.is_valid():
                serializer.save()
                del email_code[request.data['email']]
                return Response({'success': '注册成功'}, status=201)
            else:
                return Response({'error': '无效数据 ：' + str(serializer.errors)}, status=400)
        except Exception as e:
            return Response({'error': str(e)}, status=500)


# 验证令牌是否失效
class TokenVerifyView(APIView):
    def post(self, request):
        try:
            return Response({'status': True}, status=200)
        except Exception as e:
            return JsonResponse({'error': str(e)}, status=403)


# 利用邮箱发送消息
class SendEmailView(APIView):
    permission_classes = [IsNormalAdmin]

    def post(self, request):
        try:
            if not request.data['usernames']:
                # 获取所有用户
                users = User.objects.all()
                emails = [user.email for user in users]
                title = request.data['title']
                message = request.data['message']
                # 发送邮件
                send_mail(
                    title,
                    message,
                    DEFAULT_FROM_EMAIL,
                    emails,
                    fail_silently=False,
                )
            else:
                usernames = request.data['usernames']
                # usernames是一个list
                users = User.objects.filter(username__in=usernames)
                emails = [user.email for user in users]
                title = request.data['title']
                message = request.data['message']
                # 发送邮件
                send_mail(
                    title,
                    message,
                    DEFAULT_FROM_EMAIL,
                    emails,
                    fail_silently=False,
                )

            return Response({'message': '邮件发送成功'}, status=status.HTTP_200_OK)
        except Exception as e:
            return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


# 获取并返回邮箱验证码
class GetEmailCodeView(APIView):
    permission_classes = [AllowAny]

    def post(self, request):
        try:
            email = request.data['email']
            # 生成验证码
            code = random.randint(100000, 999999)

            send_mail(
                '希望信工-验证码',
                '您的验证码是：' + str(code),
                DEFAULT_FROM_EMAIL,
                [email],
                fail_silently=False,
                # 邮件内容
            )
            email_code[email] = str(code)
            return Response({'success': '成功'}, status=status.HTTP_200_OK)
        except Exception as e:
            return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


# 查询所有模型字段
class GetModelFieldsView(APIView):
    # 所有人都可以访问
    permission_classes = [AllowAny]

    def post(self, request):
        # 返回model_info_dict
        try:
            fields = model_info_dict

            return Response(fields, status=status.HTTP_200_OK)
        except Exception as e:
            return Response({"message": "获取字段失败：" + str(e)}, status=status.HTTP_400_BAD_REQUEST)
